home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d3 / Telnet2.6.1d3.src.sit.hqx / Telnet 2.6.1d3 source / source / main / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-13  |  39.3 KB  |  1,219 lines

  1. /****************************************************************
  2. *    NCSA Telnet for the Macintosh                                *
  3. *                                                                *
  4. *    National Center for Supercomputing Applications                *
  5. *    Software Development Group                                    *
  6. *    152 Computing Applications Building                            *
  7. *    605 E. Springfield Ave.                                        *
  8. *    Champaign, IL  61820                                        *
  9. *                                                                *
  10. *    Copyright (c) 1986-1992,                                    *
  11. *    Board of Trustees of the University of Illinois                *
  12. ****************************************************************/
  13.  
  14. #ifdef MPW
  15. #pragma segment 4
  16. #endif
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20.  
  21. #include "TelnetHeader.h"
  22. #include "parse.h"                // For our #defines
  23. #include "wind.h"                /* For WindRec structure */
  24. #include "network.proto.h"                /* For net functions */
  25. #include "debug.h"                /* For putln proto */
  26. #include "vgtek.proto.h"
  27. #include "vsdata.h"
  28. #include "vsinterf.proto.h"
  29. #include "maclook.proto.h"
  30. #include "tekrgmac.proto.h"
  31. #include "menuseg.proto.h"
  32.  
  33. #include "vr.h"
  34. #include "vr.proto.h"
  35. #include "tnae.h"
  36. #include "authencrypt.h"
  37. #include "authencrypt.proto.h"
  38. #include "wdefpatch.proto.h"
  39.  
  40. //#define    OPTS_DEBUG
  41. #ifdef    OPTS_DEBUG
  42. #define    opts_debug_print(x)    putln(x)    
  43. #include "optsdebug.h"
  44. #else
  45. #define    opts_debug_print(x)
  46. #endif
  47.  
  48. #define    SEND_NOSUPPORT_ON_SLC_INIT    1
  49.  
  50. extern short     scrn;
  51. extern WindRec    *screens;
  52.  
  53. #include "parse.proto.h"
  54.  
  55. /*********************************************************************/
  56. /*  parse
  57. *   look at the string which has just come in from outside and
  58. *   check for special sequences that we are interested in.
  59. *
  60. *   Tries to pass through routine strings immediately, waiting for special
  61. *   characters ESC and 255 to change modes.
  62. */
  63.  
  64. void parse (struct WindRec *tw, unsigned char *st, short cnt)
  65. {
  66.     short i,temptw;
  67.     unsigned char *mark,*orig;
  68. #ifdef OPTS_DEBUG
  69.     char munger[255]; 
  70. #endif
  71.     char nullbuf[] = {AUTH_NULL, AUTH_CLIENT_TO_SERVER|AUTH_HOW_ONE_WAY};
  72.     unsigned long sendlength;
  73.     short s;
  74.     unsigned char sendbuffer[1500];
  75.  
  76.     orig = st;                /* remember beginning point */
  77.     mark = st + cnt;        /* set to end of input string */
  78. /*
  79. * raw mode for debugging, passes through escape sequences and other
  80. * special characters as <27> symbols
  81. */
  82.     if (tw->termstate == DUMBTYPE)
  83.         {
  84.         for (i=0; i < cnt; i++,st++)            /* put on screen raw */
  85.             if (*st == 27 || *st > 126 && !(tw->ftpstate && gFTPServerPrefs->DoISOtranslation))
  86.                 {
  87.                 sprintf((char *)tw->parsedat,"<%d>",*st);
  88.                 VSwrite(tw->vs,(char *)tw->parsedat,strlen((char *)tw->parsedat));    /* send to virtual screen */
  89.                 }
  90.             else
  91.                 VSwrite(tw->vs,(char *) st,1);        /* BYU LSC */
  92.         }
  93.     else
  94.         {
  95.  
  96. /*
  97. *  traverse string, looking for any special characters which indicate that
  98. *  we need to change modes.
  99. */
  100.     while (st < mark) 
  101.         {
  102.         switch (tw->telstate)
  103.             {
  104.             case GS:
  105.             case ESCFOUND:
  106.                 if (tw->tektype >= 0) {    /* we'll allow the TEK */
  107.                     if ((*st == 12) || (tw->telstate == GS)) {    /* esc-FF */
  108.                         if ((*st == 12) && 
  109.                             ((tw->termstate == VTEKTYPE) || (!tw->tekclear))) {
  110.                             if (tw->termstate == VTEKTYPE)
  111.                                 putln("Entering Tek mode");
  112.                             else if (tw->curgraph > -1)
  113.                                 detachGraphics(tw->curgraph);
  114.  
  115.                             if (tw->curgraph <=  -1) {        // No current TEK window
  116.                                 temptw = VGnewwin(1,tw->vs);
  117.  
  118.                                 if (temptw > -1) {
  119.                                     Str255    scratchPstring;
  120.                                     
  121.                                     tw->curgraph = temptw;
  122.     
  123.                                     VGgiveinfo(temptw);
  124.                                     GetWTitle(tw->wind, scratchPstring);
  125.                                     PtoCstr(scratchPstring);
  126.                                     RGattach(temptw,tw->vs,(char *)scratchPstring, tw->tektype);
  127.                                 }
  128.                                 else
  129.                                     tw->telstate = STNORM;  // Can't create TEK window
  130.                             }
  131.  
  132.                             if (tw->telstate != STNORM)
  133.                                 tw->termstate = TEKTYPE;
  134.                         }
  135.  
  136.                         if (tw->telstate == GS) {
  137.                             st++;
  138.                             VGwrite(tw->curgraph,"\035",1);
  139.                         }
  140.                         else if (tw->telstate != STNORM)
  141.                             VGwrite(tw->curgraph,"\037\033\014",3);
  142.  
  143.                         tw->telstate = STNORM;
  144.                         break;
  145.                     } // FF or GS
  146.                 } // tw->tektype >= 0
  147.     
  148.                 if (*st == '^')    {            /* ESC- ^ */
  149.                     tw->termstate = RASTYPE;
  150.                     tw->telstate = STNORM;
  151.                     VRwrite("\033^",2);        /* Put it through */
  152.                     orig = ++st;
  153.                     break;
  154.                 }
  155.                 
  156.                 if (tw->termstate == TEKTYPE)
  157.                     VGwrite(tw->curgraph,"\033",1);
  158.                 else if (tw->termstate  == RASTYPE)
  159.                     VRwrite("\033",1);
  160.                 else
  161.                     VSwrite(tw->vs,"\033",1);    /* send the missing ESC */
  162.                 tw->telstate = STNORM;
  163.                 break;
  164.  
  165.  
  166. /*------------------------------------------------------------------------------*
  167.  *     IACFOUND:  This is the start of the Telnet option negotiation.  If Telnet    *
  168.  *    gets an IAC character, then negotiation data follows, and is ready to be    *
  169.  *     parsed.                                                                     *
  170.  *------------------------------------------------------------------------------*/
  171.             case IACFOUND:         /* telnet option negotiation- START */
  172.                 if (*st == 255) {        /* real data = 255 */
  173.                     orig = st;            // MP: translation mod (break will make it miss
  174.                                         // this assignment later on in the case, Jim!)
  175.                     st++;                /* real 255 will get sent */
  176.                     tw->telstate = STNORM;
  177.                     break;
  178.                 }
  179.                 if ( 239 < *st ) {
  180.                     tw->telstate = *st;        /* by what the option is */
  181.                     st++;
  182.                     break;
  183.                 }
  184.                 tw->telstate = STNORM;
  185.                 orig=st;
  186.                 break;
  187.  
  188.  
  189.             case TEL_EOF:        /* BYU LSC */
  190. #ifdef OPTS_DEBUG
  191.                 sprintf(munger,"RECV: %s",telstates[tw->telstate - TEL_SE]);
  192.                 opts_debug_print(munger); 
  193. #endif
  194.                 orig=st;
  195.                 tw->telstate=STNORM;
  196.                 break;
  197.  
  198.             case TEL_EL:                /* thanx Quincey!!! */
  199.             case TEL_EC:
  200.             case TEL_AYT:
  201.             case TEL_AO:
  202.             case TEL_IP:
  203.             case TEL_BREAK:
  204.             case TEL_DM:
  205.             case TEL_NOP:
  206.             case TEL_SE:
  207. #ifdef OPTS_DEBUG
  208.                 sprintf(munger,"RECV: %s",telstates[tw->telstate - TEL_SE]);
  209.                 opts_debug_print(munger); 
  210. #endif
  211.                 tw->telstate = STNORM;
  212.                 orig=st;
  213.  
  214.  
  215.             case TEL_GA:
  216.                 orig=st;
  217.                 tw->telstate = STNORM;
  218.                 break;
  219.  
  220.  
  221.  
  222. /*------------------------------------------------------------------------------*
  223.  *     Negotiate DOTEL:  sent by the server whenever it wants the client to do     *
  224.  *    an option                                                                    *
  225.  *------------------------------------------------------------------------------*/
  226.             case TEL_DOTEL:
  227. #ifdef OPTS_DEBUG
  228.                 sprintf(munger,"RECV: %s %s",telstates[tw->telstate-TEL_SE],teloptions[*st]);
  229.                 opts_debug_print(munger); 
  230. #endif
  231.                 switch( *st) 
  232.                     {
  233.                     case  N_SGA:        /* Sure we'll supress GA */
  234.                         if (!tw->Isga) {
  235.                             tw->Isga=1;
  236.                             sprintf((char *)tw->parsedat,"%c%c%c",255,TEL_WILLTEL,*st);
  237.                             netpush(tw->port);
  238.                             netwrite(tw->port,tw->parsedat,3);
  239.                             }
  240. #ifdef OPTS_DEBUG
  241.                         sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  242.                         opts_debug_print(munger); 
  243. #endif
  244.                         tw->telstate = STNORM;
  245.                         orig = ++st;
  246.                         break;
  247.                     
  248.                     case N_TERMTYP:        /* And we'll even tell you about ourselves */
  249.                         if (!tw->Ittype) {
  250.                             tw->Ittype=1;
  251.                             sprintf((char *)tw->parsedat,"%c%c%c",255,TEL_WILLTEL,*st);
  252.                             netpush(tw->port);
  253.                             netwrite(tw->port,tw->parsedat,3);
  254.                             }
  255. #ifdef OPTS_DEBUG
  256.                         sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  257.                         opts_debug_print(munger); 
  258. #endif
  259.                         tw->telstate = STNORM;
  260.                         orig = ++st;
  261.                         break;
  262.  
  263.                     case  N_NAWS:            /* NCSA: sure, I like changing the window size! */
  264.                         tw->naws =1;        /* NCSA: this session is now NAWS */
  265.                         sprintf((char *)tw->parsedat,"%c%c%c",255,TEL_WILLTEL,*st);        /* NCSA: reply, we will to NAWS */
  266.                         netpush(tw->port);                                /* NCSA */
  267.                         netwrite(tw->port,tw->parsedat,3);                /* NCSA: send it out */
  268. #ifdef OPTS_DEBUG
  269.                         sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  270.                         opts_debug_print(munger); 
  271. #endif
  272.                         SendNAWSinfo(tw, tw->width, tw->rows);
  273. //                        sprintf((char *)tw->parsedat,"%c%c%c%c%c%c%c%c%c",IAC,TEL_SB,    /* BYU 2.4.16 */
  274. //                            N_NAWS,(char)0,(unsigned char)tw->width,        /* BYU 2.4.16 */
  275. //                            (char)0,(unsigned char)tw->rows,IAC,TEL_SE);    /* BYU 2.4.16 */
  276. //                        netpush(tw->port);                                /* BYU 2.4.16 */
  277. //                        netwrite(tw->port,tw->parsedat,9);                    /* BYU 2.4.16 */
  278. #ifdef OPTS_DEBUG
  279.                         opts_debug_print("SENT: IAC TEL_SB N_NAWS <data> IAC TEL_SE"); 
  280. #endif
  281.  
  282.                         tw->telstate = STNORM;                            /* NCSA */
  283.                         orig = ++st;                                    /* NCSA */
  284.                         break;                                            /* NCSA */
  285.  
  286.                     case N_LINEMODE:  /* Sure I'll do line mode... */
  287.                         if (tw->lineAllow)  {
  288.                             sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WILLTEL,*st++);
  289.                             netwrite(tw->port,tw->parsedat,3);
  290. #ifdef OPTS_DEBUG
  291.                             sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  292.                             opts_debug_print(munger); 
  293. #endif
  294.                             sprintf((char *)tw->parsedat,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  295.                             netwrite(tw->port,tw->parsedat,4);
  296. #ifdef OPTS_DEBUG
  297.                             opts_debug_print("SENT: IAC SB LINEMODE SLC");
  298. #endif    
  299.                             for (i=1; i<= SLC_MAX; i++){
  300.                                 if (tw->slc[i]==-1) {
  301. #ifdef    SEND_NOSUPPORT_ON_SLC_INIT
  302.                                     sprintf((char *)tw->parsedat,"%c%c%c",i,SLC_NOSUPPORT,0);
  303. #ifdef OPTS_DEBUG
  304.                                     sprintf(munger,"     %s NO_SUPPORT 0",LMoptions[i]);
  305. #endif
  306. #endif
  307.                                     }
  308.                                 else
  309.                                     {
  310.                                     sprintf((char *)tw->parsedat,"%c%c%c",i,SLC_CANTCHANGE,(char)tw->slc[i]);
  311.  
  312. #ifdef OPTS_DEBUG
  313.                                     sprintf(munger,"     %s CANTCHANGE %i",LMoptions[i],(int)tw->slc[i]);
  314. #endif
  315.                                     }
  316.                                 opts_debug_print(munger);
  317.                                 netwrite(tw->port,tw->parsedat,3);
  318.                                 }
  319.     
  320.                             opts_debug_print("SENT: IAC SE");
  321.                             sprintf((char *)tw->parsedat,"%c%c",IAC,TEL_SE);
  322.                             netwrite(tw->port,tw->parsedat,2);
  323.                             }
  324.                         else {
  325.                             sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WONTTEL,*st++);
  326.                             opts_debug_print("SENT: WONT Linemode");
  327.                             netwrite(tw->port,tw->parsedat,3);
  328.                             }
  329.                         break;
  330.  
  331.                     case N_AUTHENTICATION:        /* do auth */
  332.                         if (!tw->myopts[OPT_AUTHENTICATION-MHOPTS_BASE]) {
  333.                             if (tw->authenticate) {
  334.                                 (tw->myopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1;
  335.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WILLTEL,*st);
  336.                                 netwrite(tw->port,tw->parsedat,3);
  337. #ifdef OPTS_DEBUG
  338.                                 sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  339.                                 opts_debug_print(munger); 
  340. #endif
  341.                             } else {
  342.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WONTTEL,*st);
  343.                                 netwrite(tw->port,tw->parsedat,3);
  344. #ifdef OPTS_DEBUG
  345.                                 sprintf(munger,"SENT: WONT %s",teloptions[*st]);
  346.                                 opts_debug_print(munger); 
  347. #endif
  348.                             }
  349.                         }
  350.                         tw->telstate = STNORM;
  351.                         orig = ++st;
  352.                         break;
  353.  
  354.                     case N_ENCRYPT:             /* do encrypt */
  355.                         if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) {
  356.                             if (tw->encrypt) {
  357.                                 (tw->myopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1;
  358.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WILLTEL,*st);
  359.                                 netwrite(tw->port,tw->parsedat,3);
  360. #ifdef OPTS_DEBUG
  361.                                 sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  362.                                 opts_debug_print(munger); 
  363. #endif
  364.                             } else {
  365.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WONTTEL,*st);
  366.                                 netwrite(tw->port,tw->parsedat,3);
  367. #ifdef OPTS_DEBUG
  368.                                 sprintf(munger,"SENT: WONT %s",teloptions[*st]);
  369.                                 opts_debug_print(munger); 
  370. #endif
  371.                             }
  372.                         }
  373.                         tw->telstate = STNORM;
  374.                         orig = ++st;
  375.                         break;
  376.  
  377.                     default:                /* But, we won't do .... */
  378.                         sprintf((char *)tw->parsedat,"%c%c%c",255,TEL_WONTTEL,*st++);
  379.                         netwrite(tw->port,tw->parsedat,3);  
  380. #ifdef OPTS_DEBUG
  381.                         sprintf(munger,"SENT: WONT %s",teloptions[*(st-1)]);
  382.                         opts_debug_print(munger); 
  383. #endif
  384.                         break;
  385.                     }
  386.                 tw->telstate = STNORM;
  387.                 orig = st;
  388.                 break;
  389.  
  390.  
  391. /*------------------------------------------------------------------------------*
  392.  *     Negotiate DONTTEL:  sent by the server whenever it wants the client to      *
  393.  *    definitely NOT do an option.  Sent to prevent client from negotiating an    *
  394.  *    unsupported option                                                            *
  395.  *------------------------------------------------------------------------------*/
  396.             case TEL_DONTTEL:
  397. #ifdef OPTS_DEBUG
  398.                 sprintf(munger,"RECV: %s %s",telstates[tw->telstate-TEL_SE],teloptions[*st]);
  399.                 opts_debug_print(munger); 
  400. #endif
  401.                 tw->telstate = STNORM;
  402.                 switch (*st++) {
  403.                     case N_ENCRYPT:                    /* dont encrypt */
  404.                     case N_AUTHENTICATION:            /* dont authenticate */
  405.                         tw->myopts[*(st-1)-MHOPTS_BASE] = 0;
  406.                         sprintf((char *)tw->parsedat,"%c%c%c", IAC, TEL_WONTTEL, *(st-1));
  407.                         netpush(tw->port);
  408.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  409. #ifdef OPTS_DEBUG
  410.                         sprintf(munger,"SENT: WONT %s", teloptions[*(st-1)]);
  411.                         opts_debug_print(munger); 
  412. #endif    
  413.                         break;
  414.                 }
  415.                 orig = st;
  416.                 break;
  417.  
  418.  
  419. /*------------------------------------------------------------------------------*
  420.  *     Negotiate WILLTEL:  sent by the client to try and get the server to use an    *
  421.  *    option.  This tells the server that the client is requesting that an option *
  422.  *     be used                                                                        *
  423.  *------------------------------------------------------------------------------*/
  424.             case TEL_WILLTEL:
  425. #ifdef OPTS_DEBUG
  426.                 sprintf(munger,"RECV: %s %s",telstates[tw->telstate-TEL_SE],teloptions[*st]);
  427.                 opts_debug_print(munger); 
  428. #endif
  429.                 tw->telstate = STNORM;
  430.                 switch(*st++) 
  431.                     {
  432.                     case N_ECHO:             /* Echo on the other end*/
  433. #ifdef    OPTS_DEBUG
  434.                         if (!tw->echo)
  435.                             opts_debug_print("tw->echo is False.");
  436. #endif
  437.                         if (!tw->echo)
  438.                             break;
  439.                         tw->echo = 0;    /* Ok, in that case they can echo... */
  440.                         changeport(scrn,scrn);
  441.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DOTEL,1);
  442.                         netpush(tw->port);
  443.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  444. #ifdef OPTS_DEBUG
  445.                         sprintf(munger,"SENT: DO %s",teloptions[*(st-1)]);
  446.                         opts_debug_print(munger); 
  447. #endif
  448.                         break;
  449.                     
  450.                     case N_SGA:                /* Supress GA */
  451. #ifdef    OPTS_DEBUG
  452.                         if (tw->Usga)
  453.                             opts_debug_print("tw->Usga is True.");
  454. #endif
  455.                         if (tw->Usga)
  456.                             break;
  457.                         tw->Usga = 1;    /* Go Ahead and supress GA */
  458.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DOTEL,3);
  459.                         netpush(tw->port);
  460.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  461. #ifdef OPTS_DEBUG
  462.                         sprintf(munger,"SENT: DO %s",teloptions[*(st-1)]);
  463.                         opts_debug_print(munger); 
  464. #endif
  465.                         break;
  466.                     
  467.                     case N_TIMING:                /* Timing Mark */
  468.                         tw->timing = 0;
  469.                         break;
  470.                     
  471.                     case N_AUTHENTICATION:        /* will auth */
  472.                         if (!tw->hisopts[OPT_AUTHENTICATION-MHOPTS_BASE]) {
  473.                             if (tw->authenticate) {
  474.                                 (tw->hisopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1;
  475.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DOTEL,OPT_AUTHENTICATION);
  476.                                 netwrite(tw->port,tw->parsedat,3);
  477. #ifdef OPTS_DEBUG
  478.                                 sprintf(munger,"SENT: WILL %s",teloptions[OPT_AUTHENTICATION]);
  479.                                 opts_debug_print(munger); 
  480. #endif
  481.                             } else {
  482.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,OPT_AUTHENTICATION);
  483.                                 netwrite(tw->port,tw->parsedat,3);
  484. #ifdef OPTS_DEBUG
  485.                                 sprintf(munger,"SENT: WONT %s",teloptions[OPT_AUTHENTICATION]);
  486.                                 opts_debug_print(munger); 
  487. #endif
  488.                             }
  489.                         }
  490.                         break;
  491.  
  492.                     case N_ENCRYPT:             /* will encrypt */
  493.                         if (!tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE]) {
  494.                             if (tw->encrypt) {
  495.                                 (tw->hisopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1;
  496.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DOTEL,OPT_ENCRYPT);
  497.                                 netwrite(tw->port,tw->parsedat,3);
  498. #ifdef OPTS_DEBUG
  499.                                 sprintf(munger,"SENT: DO %s",teloptions[OPT_ENCRYPT]);
  500.                                 opts_debug_print(munger); 
  501. #endif
  502.                             } else {
  503.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,OPT_ENCRYPT);
  504.                                 netwrite(tw->port,tw->parsedat,3);
  505. #ifdef OPTS_DEBUG
  506.                                 sprintf(munger,"SENT: DONT %s",teloptions[OPT_ENCRYPT]);
  507.                                 opts_debug_print(munger); 
  508. #endif
  509.                             }
  510.                         }
  511.                         break;
  512.  
  513.                     default:
  514.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,*(st-1));
  515.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  516. #ifdef OPTS_DEBUG
  517.                         sprintf(munger,"SENT: DONT %s",teloptions[*(st-1)]);
  518.                         opts_debug_print(munger); 
  519. #endif
  520.                     }
  521.                 orig = st;
  522.                 break;
  523.  
  524.  
  525.  
  526. /*------------------------------------------------------------------------------*
  527.  *     Negotiate WONTTEL:  The client refuses a Telnet option, and wants the         *
  528.  *    to forget about trying to negotiate it.                                        *
  529.  *------------------------------------------------------------------------------*/
  530.             case TEL_WONTTEL:
  531. #ifdef OPTS_DEBUG
  532.                 sprintf(munger,"?SENT: (WONTTEL)%s %s",telstates[tw->telstate-TEL_SE],teloptions[*st]);
  533.                 opts_debug_print(munger); 
  534. #endif
  535.                 tw->telstate = STNORM;
  536.                 switch(*st++) 
  537.                     {         /* which option? */
  538.                     case N_ECHO:             /* echo */
  539.                         if (tw->echo)
  540.                             break;
  541.                         tw->echo = 1;    /* Ok, I will echo if I have to... */
  542.                         changeport(scrn,scrn);
  543.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,N_ECHO);
  544.                         netpush(tw->port);
  545.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  546. #ifdef OPTS_DEBUG
  547.                         sprintf(munger,"SENT: %s %s",telstates[TEL_WONTTEL-TEL_SE],teloptions[*(st-1)]);
  548.                         opts_debug_print(munger); 
  549. #endif    
  550.                         break;
  551.                     
  552.                     case N_SGA:
  553.                         if (!tw->Usga)
  554.                             break;
  555.                         tw->Usga = 0;
  556.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,N_SGA);
  557.                         netpush(tw->port);
  558.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  559. #ifdef OPTS_DEBUG
  560.                         sprintf(munger,"SENT: %s %s",telstates[TEL_WONTTEL-TEL_SE],teloptions[*(st-1)]);
  561.                         opts_debug_print(munger); 
  562. #endif    
  563.                         break;
  564.                     
  565.                     case N_TIMING:                /* Timing Mark */
  566.                         tw->timing = 0;
  567.                         break;
  568.                     
  569.                     case N_ENCRYPT:                    /* wont encrypt */
  570.                     case N_AUTHENTICATION:            /* wont authenticate */
  571.                         tw->hisopts[*(st-1)-MHOPTS_BASE] = 0;
  572.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,*(st-1));
  573.                         netpush(tw->port);
  574.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  575. #ifdef OPTS_DEBUG
  576.                         sprintf(munger,"SENT: WONT %s", teloptions[*(st-1)]);
  577.                         opts_debug_print(munger); 
  578. #endif    
  579.                         break;
  580.  
  581.                     default:
  582.                         break;
  583.                     }
  584.                 orig = st;
  585.                 break;
  586.  
  587.  
  588.  
  589. /*------------------------------------------------------------------------------*
  590.  *     SUBNEGOTIATION -- If there is an SB token found, then Telnet needs to do     *
  591.  *    some subnegotiating.  The subnegotiation data follows, and needs to be put    *
  592.  *    somewhere safe.  Make sure and update the state, so that we know that        *
  593.  *    Telnet is doing some subnegotiations and not just horsing around            *
  594.  *------------------------------------------------------------------------------*/
  595.             case TEL_SB:
  596.                 tw->telstate = NEGOTIATE;        /* Guess what I'm doing... */
  597.                 orig=st;
  598.                 substate=0;                /* Defined for each */
  599.                 tw->parseIndex =0;        /* No data yet! Clear any possible garbage */
  600.                 break;
  601.  
  602.             case NEGOTIATE:
  603.                 if (substate <200) {
  604.                     switch( *st) {
  605.                         case IAC:                /* is it the famous DOUBLE-IAC??? */
  606.                             if (*(st+1) ==IAC)     /* Yes, treat as data value 255 */
  607.                                 {
  608.                                 tw->parsedat[tw->parseIndex++]=*st++;
  609.                                 /*tw->parsedat[tw->parseIndex++]=* */ st++;
  610.                                 }
  611.                             else                 /* otherwise just save it */
  612.                                 {
  613.                                 tw->parsedat[tw->parseIndex]='\0';
  614.                                 substate=*st++;
  615.                                 }                            
  616.                             break;
  617.                         default:
  618.                             tw->parsedat[tw->parseIndex++]=*st++;
  619.                             break;
  620.                         }
  621.                     } else 
  622.                     
  623.                     {
  624.                     switch( substate)     /* subnegotiate */
  625.                         {
  626.                         case IAC:
  627.                             substate=*st++;
  628.                             if (substate==TEL_SE) {
  629.                                 switch( tw->parsedat[0]) 
  630.                                     {
  631. /*------------------------------------------------------------------------------*
  632.  *     SUBNegotiate Termtype:  send the term type data now                            *
  633.  *------------------------------------------------------------------------------*/
  634.                                     case N_TERMTYP:            
  635.                                         if (tw->parsedat[1]==1) 
  636.                                             {
  637.                                             char s[255], termtmp[40];
  638.                                             BlockMove(tw->answerback, termtmp, 32);
  639.                                             PtoCstr((StringPtr)termtmp);
  640.     #ifdef OPTS_DEBUG
  641.                                             sprintf(munger,"RECV: SB TERMINAL-TYPE SEND\r\nSEND: SB TERMINAL-TYPE IS %s\r\n",termtmp);
  642.                                             opts_debug_print(munger); 
  643.     #endif
  644.                                             netpush(tw->port);
  645.                                             netwrite(tw->port,"\377\372\030\000",4);
  646.                                             netpush(tw->port);
  647.                                             sprintf(s,"%s\377\360",termtmp);
  648.                                             netwrite(tw->port, s, strlen(s));
  649.                                             }
  650.                                         break;
  651.                                         
  652. /*------------------------------------------------------------------------------*
  653.  *     SUBNegotiate ENCRYPTION:                                                     *
  654.  *------------------------------------------------------------------------------*/
  655.                                     case N_ENCRYPT:    {
  656.                                         sendlength = sizeof(sendbuffer);
  657.                                         s = encrypt_suboption((tnParams **)&tw->aedata, tw->parsedat,
  658.                                                               tw->parseIndex,
  659.                                                               sendbuffer, &sendlength, getcname(tw), 
  660.                                                               tw->hisopts[OPT_ENCRYPT - MHOPTS_BASE], 
  661.                                                               tw->myopts[OPT_ENCRYPT - MHOPTS_BASE]);
  662.                                         netportencryptstate(tw->port, (Ptr)tw->aedata);
  663.                                         encryptStatechange(tw);
  664.  
  665.                                         /*
  666.                                          * If we turned on encryption, we must decrypt the rest of the buffer.
  667.                                          */
  668.                                         if (s == TNREP_START_DECRYPT) {
  669.                                             unsigned char *cp = st;
  670.                                             while (cp < mark) {
  671.                                                 *cp = decrypt((tnParams *)tw->aedata, (long)(*cp));
  672.                                                 cp++;
  673.                                             }
  674.                                         }
  675.  
  676.                                         if (sizeof(sendbuffer) - sendlength)
  677.                                             netwrite(tw->port, sendbuffer, sizeof(sendbuffer)-sendlength);
  678.                                         
  679.                                         /*
  680.                                          * transfer the encrypting flag here, after the buffer 
  681.                                          * with encrypt-start has gone out.
  682.                                          */
  683.                                         if (((tnParams *)tw->aedata)->startencrypting) {
  684.                                             ((tnParams *)tw->aedata)->startencrypting = false;
  685.                                             ((tnParams *)tw->aedata)->encrypting = true;
  686.                                         }
  687.                                     }
  688.                                     break;
  689.  
  690. /*------------------------------------------------------------------------------*
  691.  *     SUBNegotiate Authentication:  send the authentication data now                 *
  692.  *------------------------------------------------------------------------------*/
  693.                                     case N_AUTHENTICATION:            
  694.                                         sendlength = sizeof(sendbuffer);
  695.                                         auth_suboption((tnParams **)&tw->aedata, tw->parsedat,
  696.                                                        tw->parseIndex,
  697.                                                        sendbuffer, &sendlength, getcname(tw), 
  698.                                                        tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE], 
  699.                                                        tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]);
  700.                                         if (sizeof(sendbuffer) - sendlength)
  701.                                             netwrite(tw->port, sendbuffer, sizeof(sendbuffer)-sendlength);
  702.                                         break;
  703.                                         
  704. /*------------------------------------------------------------------------------*
  705.  *     SUBNegotiate Linemode:  set up local characters, modes, and such            *
  706.  *------------------------------------------------------------------------------*/
  707.                                     case N_LINEMODE:
  708.                                         switch(tw->parsedat[1])
  709.                                             {
  710.                                             char s[80];
  711.  
  712.                                             case L_MODE:    /* change mode */
  713. #ifdef OPTS_DEBUG
  714.                                                 strcpy(s, "RECV: SB LINEMODE MODE => ");
  715.                                                 DemangleLineModeShort(s, tw->parsedat[2]);
  716.                                                 opts_debug_print(s);
  717. #endif
  718.                                                 if (tw->lineAllow) {            // First make sure we allowed linemode in the first place.
  719.                                                     // RFC 1184 says client should ignore MODE negotiations with the MODE_ACK bit set, and should not
  720.                                                     //    generate a response if the negotiated MODE matches the current MODE
  721.                                                     if (!((tw->parsedat[2] & L_MODE_ACK) || ((tw->parsedat[2] & L_MODE_MASK) == tw->lmode))) {
  722.                                                     
  723.                                                         // This is a hack.  Accept the state of L_EDIT and L_TRAPSIG that the server wants.  If
  724.                                                         // the server only wants zero, one, two or both of those bits, generate an ack.  Otherwise
  725.                                                         // send the server a mode that masks out all requested bits except EDIT and TRAPSIG.
  726.                                                         
  727.                                                         // (Now, since we only support L_EDIT and/or L_TRAPSIG, if those are the only modes requested,)
  728.                                                         //    (send an ACK of that MODE to the server.)
  729.                                                         
  730.                                                         tw->lmode = (tw->parsedat[2] & (L_EDIT | L_TRAPSIG));    // Accept the mode.
  731.                                                         
  732.                                                         if ((tw->parsedat[2] & (L_EDIT | L_TRAPSIG)) == tw->parsedat[2]) {
  733.                                                             tw->parsedat[2] |= L_MODE_ACK;    // Set the MODE_ACK bit
  734.                                                             }
  735.                                                         // We got a MODE bit we dont support, mask out just what we support and send it back, UNacked.
  736.                                                         else {
  737.                                                             tw->parsedat[2] = tw->parsedat[2] & (L_EDIT | L_TRAPSIG);
  738.                                                             }
  739.  
  740.                                                         sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_MODE);
  741.                                                         netwrite(tw->port,s,4);
  742.                                                         sprintf(s,"%c%c%c",tw->parsedat[2],IAC,TEL_SE);
  743.                                                         netwrite(tw->port,s,3); 
  744. #ifdef OPTS_DEBUG
  745.                                                         opts_debug_print("SENT: IAC SB");
  746.                                                         strcpy(s, "SENT: LM MODE = ");
  747.                                                         DemangleLineModeShort(s, tw->parsedat[2]);
  748.                                                         opts_debug_print(s);
  749.                                                         opts_debug_print("SENT: IAC SE");
  750. #endif
  751.                                                     }
  752. #ifdef OPTS_DEBUG
  753.                                                     else {
  754.                                                         strcpy(s, "LINEMODE MODE = ");
  755.                                                         DemangleLineModeShort(s, tw->parsedat[2]);
  756.                                                         opts_debug_print(s);
  757.                                                         if (tw->parsedat[2] & L_MODE_ACK) 
  758.                                                             opts_debug_print("\tignored 'cause MODE_ACK was set.");
  759.                                                         else
  760.                                                             opts_debug_print("\tIMPLICITLY ACCEPTED.");
  761.                                                         strcpy(s, "Curr Linemode = ");
  762.                                                         DemangleLineModeShort(s, tw->lmode);
  763.                                                         opts_debug_print(s);
  764.                                                     }
  765. #endif
  766.                                                     
  767.                                                 }
  768.                                                 break;
  769.                                             
  770.                                             case TEL_DOTEL:    
  771. #ifdef OPTS_DEBUG
  772.                                                 sprintf(munger,"RECV: SB LINEMODE DO %c", tw->parsedat[2]);
  773.                                                 opts_debug_print(munger);
  774. #endif
  775.                                                 netwrite(tw->port,"\377\372\042",3);
  776.                                                 sprintf(s,"%c\002\377\360",TEL_WONTTEL);
  777.                                                 opts_debug_print("SENT: IAC SB LINEMODE WONT FORWARDMASK IAC SE");
  778.                                                 netwrite(tw->port,s,strlen(s));
  779.                                                 break;
  780.  
  781.                                             case TEL_WILLTEL:
  782. #ifdef OPTS_DEBUG
  783.                                                 sprintf(munger,"RECV: SB LINEMODE WILL %c", tw->parsedat[2]);
  784.                                                 opts_debug_print(munger);
  785. #endif
  786.                                                 netwrite(tw->port,"\377\372\042",3);
  787.                                                 sprintf(s,"%c\002\377\360",TEL_DONTTEL);
  788.                                                 opts_debug_print("SENT: IAC SB LINEMODE DONT FORWARDMASK IAC SE");
  789.                                                 netwrite(tw->port,s,strlen(s));
  790.                                                 break;
  791.  
  792.  
  793.                                             case L_SLC:        /* set local chars */
  794.                                                 {
  795.                                                 short    lmslcflag = 0;
  796. #ifdef OPTS_DEBUG
  797.                                                 sprintf(munger,"RECV: SB LINEMODE SLC");
  798.                                                 opts_debug_print(munger);
  799.                                                 for(i=2;(tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3) {
  800.                                                     if(tw->parsedat[i+1] & SLC_AWK)
  801.                                                         sprintf(munger,"     %s %s|AWK %d",LMoptions[tw->parsedat[i]],LMflags[tw->parsedat[i+1] & SLC_LEVELBITS],tw->parsedat[i+2]);
  802.                                                     else
  803.                                                         sprintf(munger,"     %s %s %d",LMoptions[tw->parsedat[i]],LMflags[tw->parsedat[i+1] & SLC_LEVELBITS],tw->parsedat[i+2]);
  804.                                                     opts_debug_print(munger);
  805.                                         // 2.6b16.1            if ((unsigned char)(tw->parsedat[i+2])==IAC) i++;
  806.                                                     }    /* end for */
  807. #endif
  808.  
  809.                                                 for (i=2, lmslcflag=0; (tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3) {
  810.  
  811.                                                     // If func = 0, skip it 'cause we are the client.
  812. //                                                    if (tw->parsedat[i] == 0)
  813. //                                                        continue;
  814.                                                     
  815.                                                     // If it's a function we don't know about, say we don't support it.  If the server is telling
  816.                                                     // us he doesn't support it, just ignore him.
  817.                                                     if (tw->parsedat[i] > SLC_MAX) {
  818.                                                         if ((tw->parsedat[i+1] & SLC_LEVELBITS) != SLC_NOSUPPORT) {
  819.                                                             if (!lmslcflag) {
  820.                                                                 lmslcflag = 1;        // Do this only once
  821.                                                                 sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  822.                                                                 netwrite(tw->port,s,4);
  823.                                                                 opts_debug_print("SENT: IAC SB LINEMODE SLC");
  824.                                                                 }
  825.                                                             sprintf(s,"%c%c%c",tw->parsedat[i],SLC_NOSUPPORT,0);
  826. #ifdef OPTS_DEBUG
  827.                                                             sprintf(munger,"     %d SLC_NOSUPPORT 0",tw->parsedat[i]);
  828.                                                             opts_debug_print(munger);
  829. #endif
  830.                                                             netwrite(tw->port,s,3);
  831.                                                         }
  832.                                                         else
  833.                                                             continue;
  834.                                                     }
  835.                                                     
  836.                                                     // RFC 1184: If we get a response that is the same as the current setting, ignore it.  Technically, we
  837.                                                     //    should check the value for a CANTCHANGE response to satisfy part 2 of Sec 5.5.  However, since we
  838.                                                     //    advertised that key as CANTCHANGE in the first place, the server should not be changing it.  This
  839.                                                     //    should be fixed later, however I don't see it causing big problems right now. - JMB 12/93
  840.                                                     
  841.                                                     if (! ((((tw->parsedat[i+1] & SLC_LEVELBITS) == SLC_NOSUPPORT) && (tw->slc[tw->parsedat[i]] == -1))
  842.                                                         || (((tw->parsedat[i+1] & SLC_LEVELBITS) == SLC_CANTCHANGE) && (tw->slc[tw->parsedat[i]] != -1)))) {
  843.                                                         // If we get to this point, the value sent to us doesn't agree with what we want.
  844.                                                         
  845.                                                             
  846.                                                         if (!(tw->parsedat[i+1] & SLC_AWK)) {
  847.                                                             if (!lmslcflag) {
  848.                                                                 lmslcflag = 1;        // Do this only once
  849.                                                                 sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  850.                                                                 netwrite(tw->port,s,4);
  851.                                                                 opts_debug_print("SENT: IAC SB LINEMODE SLC");
  852.                                                                 }
  853.                                                         
  854.                                                             if (tw->slc[tw->parsedat[i]]==-1)
  855.                                                                 {
  856.                                                                 sprintf(s,"%c%c%c",tw->parsedat[i],SLC_NOSUPPORT,0);
  857. #ifdef OPTS_DEBUG
  858.                                                                 sprintf(munger,"     %s SLC_NOSUPPORT 0",LMoptions[tw->parsedat[i]]);
  859. #endif
  860.                                                                 }
  861.                                                             else
  862.                                                                 {
  863.                                                                 sprintf(s,"%c%c%c",tw->parsedat[i],SLC_CANTCHANGE,(char)tw->slc[tw->parsedat[i]]);
  864. #ifdef OPTS_DEBUG
  865.                                                                 sprintf(munger,"     %s SLC_CANTCHANGE %d",LMoptions[tw->parsedat[i]],
  866.                                                                                             (char)tw->slc[tw->parsedat[i]]);
  867. #endif
  868.                                                                 }                                                                
  869. #ifdef OPTS_DEBUG
  870.                                                             opts_debug_print(munger);
  871. #endif
  872.                                                             netwrite(tw->port,s,3);
  873.                                         // 2.6b16.1                    if (tw->parsedat[i+2]==IAC) i++;
  874.                                                             }
  875.                                                         }
  876.                                                     }
  877.                                                     
  878.                                                 if (lmslcflag) {
  879.                                                     sprintf(s,"%c%c",IAC,TEL_SE);
  880.                                                     netwrite(tw->port,s,2);
  881.                                                     }
  882.                                                     
  883.  
  884.                                                     /* otherwise just exit */
  885.                                                     }
  886.                                                     break;
  887.                                                 
  888.                                                 default:
  889. #ifdef OPTS_DEBUG
  890.                                                     sprintf(munger, "RECV: SB LINEMODE ?? (?? = %c)", tw->parsedat[1]);
  891.                                                     opts_debug_print(munger);
  892. #endif
  893.                                                     break;
  894.  
  895.                                                 }
  896.                                         break;
  897.  
  898. /* end of all the new line-mode stuff */                                
  899.                                 
  900.                                 
  901.                                 default:
  902.                                     break;
  903.                                 }
  904.                             } // substate == TEL_SE
  905.                             orig=st;
  906.                             tw->telstate=STNORM;
  907.                             break;
  908.                         default:
  909.                             orig=st;
  910.                             tw->telstate=STNORM;
  911.                             break;
  912.                         } // switch(substate)
  913.                     }
  914.  
  915.                 break;
  916.             default:
  917.                 tw->telstate = STNORM;
  918.                 break;
  919.         } // switch(tw->telstate)
  920.  
  921. /*
  922. * quick scan of the remaining string, skip chars while they are
  923. * uninteresting
  924. */
  925.         if (tw->telstate == STNORM) {
  926. /*
  927. *  skip along as fast as possible until an interesting character is found
  928. */
  929.  
  930.             if (!tw->eightbit) {                                            /* BYU 2.4.10 */
  931.                 while (st < mark) {                                            /* BYU 2.4.10 */
  932.                     if (*st == IAC)                                         /* BYU 2.4.10 */
  933.                         break;                                                /* BYU 2.4.10 */
  934.                     else {                                                    /* BYU 2.4.10 */
  935.                         *st &= 0x7f;                                         /* BYU 2.4.10 */
  936.                         if (*st == ESC  || *st == GS)                         /* BYU 2.4.10 */
  937.                             break;                                            /* BYU 2.4.10 */
  938.                         st++;                                                /* BYU 2.4.10 */
  939.                 }    }                                                        /* BYU 2.4.10 */
  940.             } else                                                             /* BYU 2.4.10 */
  941.                 while (st < mark && *st != ESC  && *st < 255 && *st != GS)     // MP: translation mod
  942.                     st++;                                                     /* BYU 2.4.10 */
  943. /*
  944. *  send the string where it belongs
  945. */
  946.             if (!tw->timing) {
  947.                 if (tw->termstate == TEKTYPE) {
  948.                     short i;
  949.                     
  950.                     i = VGwrite( tw->curgraph,(char *) orig,  st-orig);    /* BYU LSC */
  951.                     if (i < (st - orig)) {
  952.                         detachGraphics(tw->curgraph);
  953.                         st = orig + i;
  954.                         }
  955.                     }
  956.                 else if (tw->termstate == RASTYPE) {
  957.                     short i;
  958.                     
  959.                     i= VRwrite((char *) orig, st-orig);        /* BYU LSC */
  960.                     if (i <(st-orig)) {
  961.                         tw->termstate = VTEKTYPE;
  962.                         st = orig +i;                /* Next char to parse */
  963.                         }
  964.                     }
  965.                 else 
  966.                     VSwrite( tw->vs,(char *) orig,st-orig);    /* BYU LSC - send to virtual VT102 */
  967.                 }
  968.  
  969.             orig = st;                /* forget what we have sent already */
  970.  
  971.             if (st < mark)
  972.                 switch (*st) {
  973.                     case 255:            /* telnet IAC */
  974.                         tw->telstate = IACFOUND;
  975.                         st++;
  976.                         break;
  977.                     case GS:
  978.                         if (tw->telstate != GS) {
  979.                             tw->telstate = GS;
  980.                             }
  981.                         else
  982.                             tw->telstate = STNORM;
  983.                         st++;
  984.                         break;
  985.                         
  986.                     case ESC:            /* ESCape code */
  987.                         if (st == mark-1 || *(st+1) == 12 || *(st+1) == '^' ) {
  988.                             tw->telstate = ESCFOUND;
  989.                         }
  990.                         st++;            /* strip or accept ESC char */
  991.                         break;
  992.     
  993.                     default:
  994.                         if (*st++ > 127) {
  995.                             if (st==mark)                            /*new addition */
  996.                                 VSwrite(tw->vs,(char *) orig,1);    /* BYU LSC */
  997.                              }
  998.                         break;
  999.                 }    // switch(*st)
  1000.             } // tw->telstate == STNORM
  1001.     } // while (st < mark)
  1002.     } // tw->termstate != DUMBTYPE
  1003. } /* parse */
  1004.  
  1005. void    SendNAWSinfo(WindRec *s, short horiz, short vert)
  1006. {
  1007.     char            blah[20];
  1008.     unsigned char    height, width;
  1009.  
  1010.     height = vert & 0xff;
  1011.     width = horiz & 0xff;
  1012.     
  1013.     /* 931112, ragge, NADA, KTH, ugly patch to not send IAC as window size  */
  1014.     if(height == 0xFF) height = 0xFE;
  1015.     if(width == 0xFF) width = 0xFE;
  1016.  
  1017.     netpush (s->port);
  1018.  
  1019. /* NCSA: syntax for command is:  IAC SB NAWS widthHI widthLO heightHI heightLO IAC SE */
  1020.  
  1021.     netwrite(s->port,"\377\372\037\000",4);
  1022.     sprintf(blah,"%c\000", width);
  1023.     netwrite(s->port,blah,2);
  1024.     sprintf(blah,"%c\377\360", height);
  1025.     netwrite(s->port,blah,3);
  1026.     opts_debug_print("SENT: IAC SB NAWS <data> IAC SE");        
  1027. }
  1028.  
  1029. /*
  1030.  * Implementation specific Kerberos routines
  1031.  */
  1032.  
  1033.  
  1034. /*
  1035.  * send_auth_opt
  1036.  */
  1037. void send_auth_opt (struct WindRec *tw)
  1038. {
  1039.     unsigned char *cp, buf[30];
  1040.     
  1041.     cp = buf;
  1042.     if (tw->authenticate) {
  1043.         sprintf((char *)cp, "%c%c%c", IAC, TEL_WILLTEL, OPT_AUTHENTICATION);    /* will authenticate */
  1044.         cp += 3;
  1045.         (tw->myopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1;
  1046.  
  1047.         if (tw->encrypt) {
  1048.             sprintf((char *)cp, "%c%c%c", IAC, TEL_WILLTEL, OPT_ENCRYPT);        /* will encrypt */
  1049.             cp += 3;
  1050.             (tw->myopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1;
  1051.         }
  1052.         netpush(tw->port);
  1053.         netwrite(tw->port, buf, cp - buf);
  1054.     }
  1055. }
  1056.  
  1057.  
  1058. /*
  1059.  * getcname
  1060.  * Return a pointer to the cannonical host name
  1061.  */
  1062. char *getcname (WindRec *tw)
  1063. {
  1064.     char *cp;
  1065.     static char *b, buf[100];
  1066.  
  1067.     cp = 0;
  1068.     if (tw->cannon[0])
  1069.         cp = tw->cannon;
  1070.  
  1071. //    Doing the following is bad because we disposed of our init params!
  1072. //    else if ((*(*(ConnInitParams **)(tw->myInitParams))->session)->hostname)
  1073. //        cp = (char *)(*(*(ConnInitParams **)(tw->myInitParams))->session)->hostname;
  1074.  
  1075.     /* make a local copy to avoid locking handles */
  1076.     if (cp) {
  1077.         b = buf;        
  1078.         while (*cp)
  1079.             *b++ = *cp++;            
  1080.         *b++ = '\0';
  1081.         return buf;
  1082.     }
  1083.  
  1084.     return cp;
  1085. }
  1086.  
  1087.  
  1088. /*
  1089.  * encryptStatechange
  1090.  * Called when the encryption state changes
  1091.  */
  1092. #define kOurHit    32
  1093. void encryptStatechange (struct WindRec *tw)
  1094. {
  1095.     MyWDEFPatch(zoomDocProc , tw->wind, wDraw, kOurHit);
  1096. }
  1097.  
  1098. void DemangleLineMode(char *s, short mode)
  1099. {
  1100. #ifdef OPTS_DEBUG
  1101.     short     i;
  1102.     
  1103.     for (i=0; i<5; i++) {
  1104.         if (mode & (1 << i))
  1105.             strcat(s, LMmodes[i]);
  1106.     }
  1107. #endif
  1108. }
  1109.  
  1110. void DemangleLineModeShort(char *s, short mode)
  1111. {
  1112. #ifdef OPTS_DEBUG
  1113.     short     i;
  1114.     
  1115.     for (i=0; i<5; i++) {
  1116.         if (mode & (1 << i))
  1117.             strcat(s, LMmodeBits[i]);
  1118.         else
  1119.             strcat(s," ");
  1120.     }
  1121. #endif
  1122. }
  1123.  
  1124. #if 0    // Temp storage space - JMB 2.6b16.1
  1125.                                                 /* First check to see if we need to reply */
  1126.                                                 for (i=2;(tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3) {
  1127.                                                     if (!(tw->parsedat[i+1] & SLC_AWK)) break;
  1128.                                                     if ((unsigned char)(tw->parsedat[i+2])==IAC) i++;
  1129.                                                     }
  1130.  
  1131.                                                 /* if we do then send a reply */
  1132.                                                 if ((tw->parsedat[i]!=IAC) && (tw->parsedat[i]!='\0')) {
  1133.                                                 //    sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  1134.                                                 //    netwrite(tw->port,s,4);
  1135.                                                 //    opts_debug_print("SENT: IAC SB LINEMODE SLC");
  1136.     
  1137.  
  1138. #ifdef NEWSLC
  1139.                                                     for (i=2; (tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3)
  1140.                                                         {
  1141.                                                         if (!(tw->parsedat[i+1] & SLC_AWK))        /* no response of ACK set */
  1142.                                                             {
  1143.                                                             if (tw->parsedat[i+1] != SLC_NOSUPPORT)
  1144.                                                                 {
  1145.                                                                 sprintf(s,"%c%c%c",tw->parsedat[i],SLC_NOSUPPORT,0);
  1146. #ifdef OPTS_DEBUG
  1147.                                                                 sprintf(munger,"     %s NOSUPPORT 0",LMoptions[tw->parsedat[i]]);
  1148. #endif
  1149.                                                                 }
  1150.                                                             else        /* Acknowledge the No_Support case */
  1151.                                                                 {
  1152.                                                                 sprintf(s,"%c%c%c",tw->parsedat[i],SLC_AWK|SLC_NOSUPPORT,(char)0);
  1153. #ifdef OPTS_DEBUG
  1154.                                                                 sprintf(munger,"     %s NOSUPPORT|AWK 0",LMoptions[tw->parsedat[i]]);
  1155. #endif
  1156.                                                                 }                                                                
  1157. #ifdef OPTS_DEBUG
  1158.                                                             opts_debug_print(munger);
  1159. #endif
  1160.                                                             netwrite(tw->port,s,3);
  1161.                                                             }
  1162.                                                             if ((unsigned char)(tw->parsedat[i+2])==IAC) i++;
  1163.                                                         }
  1164.  
  1165. #else
  1166.                                                     for (i=2, lmslcflag=0; (tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3) {
  1167.                                                         // RFC 1184: If we get a response that is the same as the current setting, ignore it.  Technically, we
  1168.                                                         //    should check the value for a CANTCHANGE response to satisfy part 2 of Sec 5.5.  However, since we
  1169.                                                         //    advertised that key as CANTCHANGE in the first place, the server should not be changing it.  This
  1170.                                                         //    should be fixed later, however I don't see it causing big problems right now. - JMB 12/93
  1171.                                                         if (! ((((tw->parsedat[i+2] & SLC_LEVELBITS) == SLC_NOSUPPORT) && (tw->slc[tw->parsedat[i+1]] == -1))
  1172.                                                             || (((tw->parsedat[i+2] & SLC_LEVELBITS) == SLC_CANTCHANGE) && (tw->slc[tw->parsedat[i+1]] != -1)))) {
  1173.                                                             // If we get to this point, the value sent to us doesn't agree with what we want.
  1174.                                                             
  1175.                                                                 
  1176.                                                             if (!(tw->parsedat[i+1] & SLC_AWK)) {
  1177.                                                                 if (!lmslcflag) {
  1178.                                                                     lmslcflag = 1;        // Do this only once
  1179.                                                                     sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  1180.                                                                     netwrite(tw->port,s,4);
  1181.                                                                     opts_debug_print("SENT: IAC SB LINEMODE SLC");
  1182.                                                                     }
  1183.                                                             
  1184.                                                                 if (tw->slc[tw->parsedat[i]]==-1)
  1185.                                                                     {
  1186.                                                                     sprintf(s,"%c%c%c",tw->parsedat[i],SLC_NOSUPPORT,0);
  1187. #ifdef OPTS_DEBUG
  1188.                                                                     sprintf(munger,"     %s SLC_NOSUPPORT 0",LMoptions[tw->parsedat[i]]);
  1189. #endif
  1190.                                                                     }
  1191.                                                                 else
  1192.                                                                     {
  1193.                                                                     sprintf(s,"%c%c%c",tw->parsedat[i],SLC_CANTCHANGE,(char)tw->slc[tw->parsedat[i]]);
  1194. #ifdef OPTS_DEBUG
  1195.                                                                     sprintf(munger,"     %s SLC_CANTCHANGE %d",LMoptions[tw->parsedat[i]],
  1196.                                                                                                 (char)tw->slc[tw->parsedat[i]]);
  1197. #endif
  1198.                                                                     }                                                                
  1199. #ifdef OPTS_DEBUG
  1200.                                                                 opts_debug_print(munger);
  1201. #endif
  1202.                                                                 netwrite(tw->port,s,3);
  1203.                                                                 if (tw->parsedat[i+2]==IAC) i++;
  1204.                                                                 }
  1205.                                                             }
  1206.                                                         }
  1207.                                                         
  1208. #endif
  1209.                                                     if (lmslcflag) {
  1210.                                                         sprintf(s,"%c%c",IAC,TEL_SE);
  1211.                                                         netwrite(tw->port,s,2);
  1212.                                                         }
  1213.                                                     }
  1214.  
  1215.                                                     /* otherwise just exit */
  1216.                                                     }
  1217.                                                     break;
  1218. #endif
  1219.